#pragma once

#include <iostream>
#include <string>
#include <vector>
#include <sstream>
const std::string HttpSep = "\r\n";
const std::string homepage = "index.html";
const std::string wwwroot = "./wwwroot";
#include <fstream>
class HttpRequest
{
public:
    HttpRequest() : _req_blank(HttpSep)
    {
    }
    bool GetLine(std::string &str, std::string *line)
    {
        auto pos = str.find(HttpSep);
        if (pos == std::string::npos)
            return false;
        *line = str.substr(0, pos); // \r\n
        str.erase(0, pos + HttpSep.size());
        return true;
    }
    void Deserialize(std::string &request)
    {
        std::string line;
        bool ok = GetLine(request, &line);
        if (!ok)
            return;
        _req_line = line;

        while (true)
        {
            bool ok = GetLine(request, &line);
            if (ok && line.empty())
            {
                _req_content = request;
                break;
            }
            else if (ok && !line.empty())
            {
                _req_header.push_back(line);
            }
            else
            {
                break;
            }
        }
    }
    void DebugHttp()
    {
        std::cout << "_req_line" << _req_line << std::endl;
        for (auto &line : _req_header)
        {
            std::cout << "---> " << line << std::endl;
        }
        std::cout << "_req_blank: " << _req_blank << std::endl;
        std::cout << "_req_content: " << _req_content << std::endl;
        std::cout << "Method: " << _method << std::endl;
        std::cout << "url: " << _url << std::endl;
        std::cout << "http_version: " << _http_version << std::endl;
    }
    void ParseReqLine()
    {
        std::stringstream ss(_req_line);
        ss >> _method >> _url >> _http_version;

        if (_url == "/")
        {
            _path += _url;
            _path += homepage;
        }
        else
        {
            _path += _url;
        }
    }
    void ParseSuffix()
    {
        auto pos = _path.rfind(".");
        if (pos == std::string::npos)
            _suffix = ".html";
        else
            _suffix = _path.substr(pos);
    }
    std::string Suffix()
    {
        return _suffix;
    }
    ////解析第一行
    void Parse()
    {
        // 分析请求行
        ParseReqLine();
        // 2. wwwroot/dira/dirb/x.html, 提取后缀 wwwroot/index.html wwwroot/image/1.png
        ParseSuffix();
    }
std::string GetFileContentHelper(const std::string &path)
{
    std::ifstream in(path, std::ios::binary);
    if(!in.is_open())
    {
        return "";
    }
    in.seekg(0,in.end);
    int filesize=in.tellg();
    in.seekg(0,in.beg);
    std::string content;
    content.resize(filesize);
    in.read((char*)content.c_str(),filesize);
    in.close();
    cout<<"content是"<<content<<endl;
    return content;
}
std::string GetFileContent()
    {
        return GetFileContentHelper(_path);
    }

std::string Get_404()
    {
        return GetFileContentHelper("./wwwroot/404.html");
    }
std::string Url()
    {
        return _url;
    }
    std::string Path()
    {
        return _path;
    }
    ~HttpRequest()
    {
    }

private:
    std::string _req_line;
    std::vector<std::string> _req_header;
    std::string _req_blank;
    std::string _req_content;
    // 解析之后的内容
private:
    std::string _method;
    std::string _url;
    std::string _http_version;
    std::string _suffix;
    std::string _path;
};
const std::string BlankSep = " ";
const std::string LineSep = "\r\n";

class HttpResponse
{
public:
    HttpResponse() : _http_version("HTTP/1.0"), _status_code(200), _status_code_desc("OK"), _resp_blank(LineSep)
    {
    }
    void SetCode(int code)
    {
        _status_code = code;
    }
    void SetDesc(const std::string &desc)
    {
        _status_code_desc = desc;
    }
    void MakeStatusLine()
    {
        _status_line = _http_version + BlankSep + std::to_string(_status_code) + BlankSep + _status_code_desc + LineSep;
    }
    void AddHeader(const std::string &header)
    {
        _resp_header.push_back(header);
    }
    void AddContent(const std::string &content)
    {
        _resp_content = content;
    }
    std::string Serialize()
    {
        std::string response_str = _status_line;
        for (auto &header : _resp_header)
        {
            response_str += header;
        }
        response_str += _resp_blank;
        response_str += _resp_content;

        return response_str;
    }
    ~HttpResponse() {}

private:
    std::string _status_line;
    std::vector<std::string> _resp_header;
    std::string _resp_blank;
    std::string _resp_content; // body

    // httpversion StatusCode StatusCodeDesc
    std::string _http_version;
    int _status_code;
    std::string _status_code_desc;
};
// const std::string BlankSep=" ";
// const std::string LineSep="\r\n";
// class HttpResponse
// {
// public:
// HttpResponse():_status_code(200),_http_version("HTTP/1/0"),_status_code_desc("ok"),_resp_blank(LineSep)
// {};
//     void AddHeader(const std::string &header)
//     {
//         _resp_header.push_back(header);
//     }
//     void SetCode(int code)
//     {
//         _status_code=code;
//     }
//     void SetDesc(const std::string &desc)
//     {
//         _status_code_desc = desc;
//     }
//     void MakeStatusLine()
//     {
//         _status_line = _http_version + BlankSep + std::to_string(_status_code) + BlankSep + _status_code_desc + LineSep;
//     }
//  void AddContent(std::string &content)
//  {
//     _resp_content=content;
//  }
// std::string Serialize()
// {
//     std::string response_str=_status_line;
//     for(auto &header:_resp_header)
//     {
//     response_str+=header;
//     }
// response_str+=_resp_blank;
// response_str+=_resp_content;
// return response_str;
// }
// ~HttpResponse()
// {};
// private:
//  std::string _status_line;
//  std::vector<std::string> _resp_header;
//  std::string _resp_blank;
//  std::string _resp_content;
//  //
//  std::string _http_version;
//  int _status_code;
//  std::string _status_code_desc;
// };